"""
    此模块的作用是组织数据库中的K线数据
"""


from fastapi import APIRouter, Depends, HTTPException, Query
from klineapp.models import AsyncSessionFactory
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import text
from common.utils import DBUtil
from common.log import LOG, LogLevel
from klineapp.func import process_symbols_concurrently, make_main_table
import akshare as ak


router = APIRouter(prefix="/k", tags=["组织k线数据"])


# 函数依赖（获取异步数据库会话）
async def get_asyncsession():
    session = AsyncSessionFactory()
    try:
        yield session
    finally:
        await session.close()


# 初始化k线数据
@router.get("/akinit", description="初始化K线数据库")
async def init_klinedata(session: AsyncSession=Depends(get_asyncsession)):
    """
    初始化K线数据
    :param session: 数据库会话
    :return: 成功消息
    """
    try:
        async with session.begin():
            # 1. 删除现有的K线数据表
            await DBUtil(session).drop_all_tables()

            # 2. 创建k线数据表
            #  2.1 获取当前所有主力合约的代码
            LOG(LogLevel.INFO) << "正在获取主力合约代码..." << "\n"
            futures = ak.futures_display_main_sina() # 耗时约10s
            make_main_table(futures)  # 创建主表
            LOG(LogLevel.INFO) << f"获取到{len(futures)}个主力合约代码，正在依次建表并将数据入库..." << "\n"
            #  2.2 并发处理所有合约
            await process_symbols_concurrently(futures)
            return {"message": "K线数据初始化成功！"}
    except RuntimeError as e:
        LOG(LogLevel.ERROR) << f"{str(e)}" << "\n"
        raise HTTPException(status_code=500, detail="部分数据加载失败，可能是接口不稳定！")
    except Exception as e:
        LOG(LogLevel.ERROR) << f"初始化K线数据失败: {str(e)}" << "\n"
        raise HTTPException(status_code=500, detail="初始化K线数据库失败，请服务端查看情况！")


# 获取某个品种某个周期上的k线数据
@router.get("/get_k", description="获取某个品种某个周期上的k线数据")
async def get_k(
    session: AsyncSession=Depends(get_asyncsession),
    symbol: str = Query(description="期货品种代码，例如 zn0"),
    period: str = Query("5min", description="K线周期，支持 1min/5min/30min/2h/1d"),
):
    try:
        table_name = f"{symbol.lower()}_{period}"
        query = f"""
            SELECT 
                datetime, open, high, low, close, volume, hold
            FROM {table_name} ORDER BY datetime DESC
        """

        # 4. 执行查询
        result = await session.execute(text(query))
        rows = result.mappings().all()

        # 5. 格式化返回数据
        klines = [{
            "datetime": row["datetime"],
            "open": row["open"],
            "high": row["high"],
            "low": row["low"],
            "close": row["close"],
            "volume": row["volume"],
            "hold": row["hold"]
        } for row in rows]

        return {
            "symbol": symbol,
            "period": period,
            "lines": len(klines), # 行数
            "data": klines
        }

    except Exception as e:
        LOG(LogLevel.ERROR) << f"获取k线数据失败: {str(e)}" << "\n"
        raise HTTPException(status_code=500, detail=f"获取K线数据失败！")